package com.quectel.business.common.mobileuser;

import com.quectel.business.common.sms.SmsBusiness;
import com.quectel.business.common.thirdconfig.ThirdPlatformConfigBusiness;
import com.quectel.constant.PushConstants;
import com.quectel.constant.core.mobileuser.MobileUserMsgConstants;
import com.quectel.constant.core.officialaccount.OfficialAccountsConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.constant.sys.SysConfigKeyConstants;
import com.quectel.core.module.mobileuser.dto.MobileUserDto;
import com.quectel.core.module.mobileuser.dto.MobileUserMsgDto;
import com.quectel.core.module.mobileuser.service.MobileUserMsgService;
import com.quectel.core.module.officialaccounts.dto.OfficialAccountsBindingDto;
import com.quectel.core.module.officialaccounts.service.OfficialAccountsBindingService;
import com.quectel.core.module.thirdconfig.dto.item.WechatOfficial;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.sdk.officialaccounts.OfficialAccountsUtils;
import com.quectel.sdk.officialaccounts.model.WechatMsgPushVo;
import com.quectel.sys.module.sys.service.SysConfigService;
import com.quectel.util.thread.ThreadPoolUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * 人员消息推送
 *
 * @author: caolu
 * @email: louis.cao@quectel.com
 * @date: 2022-05-10 14:52:00
 */
@Component
@Slf4j
public class MobileUserMsgBusiness implements DisposableBean {

    @DubboReference
    private MobileUserMsgService mobileUserMsgService;
    @DubboReference
    private OfficialAccountsBindingService officialAccountsBindingService;

    @DubboReference
    private VillageService villageService;

    @DubboReference
    private SysConfigService sysConfigService;
    @Autowired
    private ThirdPlatformConfigBusiness thirdPlatformConfigBusiness;
    @Autowired
    private SmsBusiness smsBusiness;

    private static final ThreadPoolExecutor PUSH_MSG_POOL = ThreadPoolUtils.createCommonIOBoundPool("push-msg-pool");

    @Override
    public void destroy() throws Exception {
        ThreadPoolUtils.shutdown(PUSH_MSG_POOL);
    }

    /**
     * @param tenantId           租户id
     * @param villageId          小区id
     * @param mobileUsers        推送消息的人多个
     * @param sourceType         消息类型
     * @param sourceId           每种消息类型下对应的id
     * @param title              消息标题 传入null则为默认的消息
     * @param content            消息内容
     * @param msgDurableDatabase 是否存储消息到关系型数据库
     * @param pushTypes          推送类型可以有多个 null或者空代表不推送
     */
    public void pushMsg(
            Long tenantId,
            Long villageId,
            List<MobileUserDto> mobileUsers,
            MobileUserMsgConstants.SourceType sourceType,
            Long sourceId,
            String title,
            String content,
            boolean msgDurableDatabase,
            PushConstants.PushType[] pushTypes

    ) {
        if (CollectionUtils.isEmpty(mobileUsers)) {
            return;
        }

        PUSH_MSG_POOL.submit(() -> {
            Date nowDate = new Date();
            if (msgDurableDatabase) {
                List<MobileUserMsgDto> durableMsgList = mobileUsers.stream().map(mobileUser -> {
                    MobileUserMsgDto mobileUserMsgDto = new MobileUserMsgDto();
                    mobileUserMsgDto.setMobileUserId(mobileUser.getId());
                    mobileUserMsgDto.setSourceType(sourceType.getType());
                    mobileUserMsgDto.setSourceId(sourceId);
                    mobileUserMsgDto.setTitle(title == null ? sourceType.getDefaultTitle() : title);
                    mobileUserMsgDto.setContent(content);
                    mobileUserMsgDto.setCreateTime(nowDate);
                    mobileUserMsgDto.setReadStatus(SystemConstants.NO);
                    return mobileUserMsgDto;
                }).collect(Collectors.toList());
                mobileUserMsgService.saveBatch(durableMsgList);
            }
            if (Arrays.stream(pushTypes).anyMatch(PushConstants.PushType.WECHAT_OFFICIAL::equals)) {
                pushToWechat(tenantId, villageId, mobileUsers, sourceType, sourceId, title, content);
            }
            if (Arrays.stream(pushTypes).anyMatch(PushConstants.PushType.SMS::equals)) {
                pushToSms(tenantId, mobileUsers, title, content);
            }
        });


    }

    private void pushToSms(Long tenantId, List<MobileUserDto> mobileUserDtos, String title, String content) {
        for (MobileUserDto mobileUser : mobileUserDtos) {
            smsBusiness.sendCommonMsg(tenantId, mobileUser.getMobile(), title, content);
        }
    }

    private void pushToWechat(Long tenantId, Long villageId, List<MobileUserDto> mobileUsers, MobileUserMsgConstants.SourceType sourceType, Long sourceId, String title, String content) {
        //微信公众号推送
        String mobileUserWebUrl = sysConfigService.getConfigValueByKey(SysConfigKeyConstants.MOBILE_USER_WEB_URL);

        for (MobileUserDto mobileUser : mobileUsers) {
            WechatOfficial wechatOfficialConfig = thirdPlatformConfigBusiness.getWechatOfficialConfig(tenantId);
            if (wechatOfficialConfig == null) {
                break;
            }
            List<OfficialAccountsBindingDto> bindings = officialAccountsBindingService.selectBy(OfficialAccountsConstants.PERSON_TYPE_MOBILE_USER,
                    mobileUser.getId(), SystemConstants.OFFICIAL_ACCOUNTS_PLATFORM_WX,
                    wechatOfficialConfig.getAppId());
            if (bindings == null || bindings.size() <= 0) {
                break;
            }
            VillageDto villageDto = villageService.selectCacheById(villageId);
            if (villageDto == null) {
                break;
            }
            try {

                Map<String, String> params = new HashMap<>();
                params.put("title", title == null ? sourceType.getDefaultTitle() : title);
                params.put("content", content);
//
                for (OfficialAccountsBindingDto binding : bindings) {
                    OfficialAccountsUtils.sendWechatMsgToUser(wechatOfficialConfig.getAppId(), wechatOfficialConfig.getAppSecret(),
                            WechatMsgPushVo.builder()
                                    .toUser(binding.getOpenId())
                                    .templateId(wechatOfficialConfig.getMsgTemplate())
                                    .linkUrl(String.format("%s?appId=%s&villageCode=%s&msgSourceType=%d&msgSourceId=%d#/login", mobileUserWebUrl, wechatOfficialConfig.getAppId(), villageDto.getCode()
                                            , sourceType.getType(), sourceId))
                                    .params(params)
                                    .build());
                }

            } catch (Exception e) {
                log.error("微信推送失败", e);
            }

        }
    }

    public static void main(String[] args) {
    }

}
